package com.steve.summary.saga.编排式.service;

import com.steve.summary.saga.编排式.domain.OrderCancelledEvent;
import com.steve.summary.saga.编排式.domain.PaymentProcessedEvent;
import com.steve.summary.saga.编排式.domain.StockUpdatedEvent;
import com.steve.summary.saga.common.model.Order;
import com.steve.summary.saga.common.model.Payment;
import com.steve.summary.saga.common.status.PaymentStatus;
import com.steve.summary.saga.common.repository.OrderRepository;
import com.steve.summary.saga.common.repository.PaymentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: STEVE
 * @Description: 支付服务，负责支付处理和退款服务
 * @since: 2025-05-28
 */
@Service
public class PaymentService {

    @Autowired
    private PaymentRepository paymentRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /**
     * 处理库存更新事件
     * 1. 如果库存更新失败，发布支付失败事件
     * 2. 如果库存更新成功，处理支付
     * 3. 发布支付处理结果事件
     */
    @Transactional
    @EventListener
    public void handleStockUpdated(StockUpdatedEvent event) {
        if (!event.isSuccess()) {
            eventPublisher.publishEvent(new PaymentProcessedEvent(
                    event.getOrderId(),
                    false,
                    "stock update failed"
            ));
            return;
        }
        try {
            Order order = orderRepository.findById(event.getOrderId())
                    .orElseThrow(() -> new RuntimeException("Order not found"));
            // 创建支付记录
            Payment payment = new Payment();
            payment.setOrderId(order.getId());
            payment.setAmount(order.getPrice());
            payment.setStatus(PaymentStatus.COMPLETED);
            paymentRepository.save(payment);
            // 发布支付成功事件
            eventPublisher.publishEvent(new PaymentProcessedEvent(
                    event.getOrderId(),
                    true,
                    "Payment processed successfully"
            ));
        } catch (Exception e) {
            // 发布支付失败事件
            eventPublisher.publishEvent(new PaymentProcessedEvent(
                    event.getOrderId(),
                    false,
                    "Payment processing failed: " + e.getMessage()
            ));
            throw e;
        }
    }

    /**
     * 处理订单取消事件
     * 执行退款操作
     */
    @Transactional
    @EventListener
    public void handleOrderCancelled(OrderCancelledEvent event) {
        Payment payment = paymentRepository.findByOrderId(event.getOrderId())
                .orElseThrow(() -> new RuntimeException("Payment not found"));
        // 更新支付状态为已退款
        payment.setStatus(PaymentStatus.REFUNDED);
        paymentRepository.save(payment);
    }

}
